package util

// Copyright 2019 Huawei Technologies Co.,Ltd.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License.  You may obtain a copy of the
// License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations under the License.

import (
	"bytes"
	"github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
	"io"
	"nft-server/config"
	"nft-server/logger"
)

var (
	endpoint   = config.GetConfig().OBSConfig.Endpoint
	ak         = config.GetConfig().OBSConfig.AK
	sk         = config.GetConfig().OBSConfig.SK
	bucketName = config.GetConfig().OBSConfig.BucketName
)

var obsClient *obs.ObsClient

const (
	urlValidityPeriod = 3600 * 2
)

func obsInit() {
	defer obs.CloseLog()
	obs.InitLog("/temp/OBS-SDK.log", 1024*1024*100, 5, obs.LEVEL_WARN, false)
}

func getObsClient() *obs.ObsClient {
	var err error
	if obsClient == nil {
		obsClient, err = obs.New(ak, sk, endpoint)
		if err != nil {
			panic(err)
		}
	}
	return obsClient
}

//在OBS中创建文件夹
func CreateFolder(filePath string) error {
	if filePath[len(filePath)-1] != '/' {
		filePath = CombineTwoString(filePath, "/")
	}
	input := &obs.PutObjectInput{}
	input.Bucket = bucketName
	input.Key = filePath
	output, err := getObsClient().PutObject(input)
	if err == nil {
		logger.Info("RequestId:%s", output.RequestId)
	} else if obsError, ok := err.(obs.ObsError); ok {
		logger.Error("Code:%s Message:%s", obsError.Code, obsError.Message)
	}
	return err
}

//上传文件
func UploadFile(obsKey string, data []byte) (string, error) {
	reader := bytes.NewReader(data)
	return UploadData(obsKey, reader)
}

//给定图片在obs上的路径，返回带授权的url，默认有效时间为1个小时
//OBSkey和Asset表中的SaveUrl等价
func GetAssetUrl(obsKey string) (string, error) {
	if len(obsKey) == 0 {
		return "", nil
	}
	getObjectInput := &obs.CreateSignedUrlInput{}
	getObjectInput.Method = obs.HttpMethodGet
	getObjectInput.Bucket = bucketName
	getObjectInput.Key = obsKey
	getObjectInput.Expires = urlValidityPeriod //1 hour
	getObjectOutput, err := getObsClient().CreateSignedUrl(getObjectInput)
	if err != nil {
		return "", err
	}
	return getObjectOutput.SignedUrl, nil
}

//上传文件--返回OBS上的URL--流式上传
func UploadData(obsKey string, fileReader io.Reader) (string, error) {
	finalKey := "/" + bucketName + "/" + obsKey
	input := &obs.PutObjectInput{}
	input.Bucket = bucketName
	input.Key = finalKey
	input.Body = fileReader
	output, err := getObsClient().PutObject(input)
	if err == nil {
		//选择查看上传成功参数
		logger.Info("Request ID:%s\n", output.RequestId)
	} else if obsError, ok := err.(obs.ObsError); ok {
		logger.Error("Code:%s\n", obsError.Code)
		logger.Error("Message:%s\n", obsError.Message)
	}
	return finalKey, nil
}

//下载文件--返回data
func DownloadFile(obsKey string) ([]byte, error) {
	input := &obs.GetObjectInput{}
	input.Bucket = bucketName
	input.Key = obsKey
	output, err := getObsClient().GetObject(input)
	var data []byte
	if err == nil {
		defer output.Body.Close()
		p := make([]byte, 1024)
		var readErr error
		var readCount int
		// 读取对象内容
		for {
			readCount, readErr = output.Body.Read(p)
			if readCount > 0 {
				data = append(data, p...)
			}
			if readErr != nil {
				break
			}
		}
	} else if obsError, ok := err.(obs.ObsError); ok {
		logger.Error("Code:%s\n", obsError.Code)
		logger.Error("Message:%s\n", obsError.Message)
	}
	return data, nil
}
